package org.shj.thread.book2.chapter08;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Channel {

	private static final int MAX_REQ = 100;
	
	/*private final Request[] reqQueue;
	private int tail;
	private int head;
	private int count;*/
	
	private BlockingQueue<Request> queue = new LinkedBlockingQueue<Request>(MAX_REQ);
	
	private final WorkerThread[] threadPool;
	
	public Channel(int threads){
		/*this.reqQueue = new Request[MAX_REQ];
		this.head = 0;
		this.tail = 0;
		this.count = 0;*/
		
		threadPool = new WorkerThread[threads];
		for(int i = 0 ; i < threadPool.length; i++){
			threadPool[i] = new WorkerThread("Worker-" + i, this);
		}
	}
	
	public void startWorkers(){
		for(int i = 0 ; i < threadPool.length; i++){
			threadPool[i].start();
		}
	}
	
	public synchronized void putRequest(Request req){
		/*while (count >= reqQueue.length){
			try{
				wait();
			}catch(InterruptedException e){
				
			}
		}
		
		
		reqQueue[tail] = req;
		tail = (tail + 1) % reqQueue.length;
		count++;
		
		notifyAll();*/
		
		
		try{
			queue.put(req);
		}catch(InterruptedException e){
			
		}
		notifyAll();	
	}
	
	public synchronized Request takeRequest(){
		/*while(count <= 0){
			try{
				wait();
			}catch(InterruptedException e){
				
			}
		}
		Request req = reqQueue[head];
		head = (head + 1) % reqQueue.length;
		count--;
		notifyAll();
		return req;*/
		
		
		Request req = null;
		while((req = queue.poll()) == null){
			try{
				wait();
			}catch(InterruptedException e){
				
			}
		}
		return req;
		
	}
}
